import * as THREE from 'three';
const AngleTol = 1;
const MaxScreenTol = 5;
const PointTol = 0.00001;

export function isEqualPoint(point1, point2) {
  let isSame = false;
  if (
    Math.abs(point1.x - point2.x) < PointTol
    && Math.abs(point1.y - point2.y) < PointTol
    && Math.abs(point1.z - point2.z) < PointTol
  ) {
    isSame = true;
  }
  return isSame;
}

export function computeIntersectPnt(line1p1, line1p2, line2p1, line2p2) {
  if (isEqualPoint(line1p1, line1p2)) {
    //!<点在线上的情况
    if (isEqualPoint(line1p1, line2p2)) {
      let interPnt = new THREE.Vector3();
      interPnt.copy(line1p1);
      return interPnt;
    } else {
      return null;
    }
  } else {
    if (isEqualPoint(line2p1, line2p2)) {
      if (isEqualPoint(line1p2, line2p1)) {
        let interPnt = new THREE.Vector3();
        interPnt.copy(line1p1);
        return interPnt;
      } else {
        return null;
      }
    } else {
      let line1a = line1p1.y - line1p2.y;
      let line1b = line1p2.x - line1p1.x;
      let line1c = line1p1.x * line1p2.y - line1p2.x * line1p1.y;

      let line2a = line2p1.y - line2p2.y;
      let line2b = line2p2.x - line2p1.x;
      let line2c = line2p1.x * line2p2.y - line2p2.x * line2p1.y;

      let d = line1a * line2b - line2a * line1b;
      if (Math.abs(d) === 0) {
        return null;
      } else {
        let x = (line1b * line2c - line2b * line1c) / d;
        let y = (line1c * line2a - line2c * line1a) / d;
        let interPnt = new THREE.Vector3(x, y, 0);
        return interPnt;
      }
    }
  }
}

export function get2DfromAL (startPoint, pnt, angle, length) {
  var P1 = [];
  //判断鼠标点的象限位置
  var px = pnt.x - startPoint.x;
  var py = pnt.y - startPoint.y;
  if (angle === 0) {
    P1[0] = length + startPoint.x;
    P1[1] = startPoint.y;
  } else if (angle === 180) {
    P1[0] = -1 * length + startPoint.x;
    P1[1] = startPoint.y;
  } else {
    if (py >= 0) {//上半平面
      if (0 < angle < 90) { /// sin/cos for all angle cases
        P1[0] = length * Math.cos(angle * Math.PI / 180) + startPoint.x;
        P1[1] = length * Math.sin(angle * Math.PI / 180) + startPoint.y;
      } else if (angle === 90) {
        P1[0] = startPoint.x;
        P1[1] = length + startPoint.y;
      } else {
        P1[0] = -1 * length * Math.cos((180 - angle) * Math.PI / 180) + startPoint.x;
        P1[1] = length * Math.sin((180 - angle) * Math.PI / 180) + startPoint.y;
      }
    } else if (py < 0) {//下半平面
      if (0 < angle < 90) {
        P1[0] = length * Math.cos(angle * Math.PI / 180) + startPoint.x;
        P1[1] = -1 * length * Math.sin(angle * Math.PI / 180) + startPoint.y;
      } else if (angle === 90) {
        P1[0] = startPoint.x;
        P1[1] = -1 * length + startPoint.y;
      } else {

        P1[0] = -1 * length * Math.cos((180 - angle) * Math.PI / 180) + startPoint.x;
        P1[1] = -1 * length * Math.sin((180 - angle) * Math.PI / 180) + startPoint.y;
      }
    }
  }
  return P1;
}

// 点到直线垂足
export function pointToLineDropFeet(point, startPoint, endPoint) {
  let dropFeet = null;
  //线的两个端点不重合，
  if (startPoint.equals(endPoint))
    return dropFeet;

  let a = endPoint.y - startPoint.y;
  let b = endPoint.x - startPoint.x;
  let A = -1 * a;
  let B = b;
  let C = -1 * b * startPoint.y + a * startPoint.x;
  let x0 = (B * B * point.x - A * B * point.y - A * C) / (A * A + B * B);
  let y0 = (A * A * point.y - A * B * point.x - B * C) / (A * A + B * B);
  dropFeet = new THREE.Vector3(x0, y0, 0);
  return dropFeet;
}

export function symmetryPoint(point, lineStartPoint, lineEndPoint) {
  let dropFeet = pointToLineDropFeet(point, lineStartPoint, lineEndPoint);
  let distanceTo = point.distanceTo(dropFeet);
  return getPointByLen(dropFeet, dropFeet.clone().sub(point).normalize(), distanceTo);
}

export function getPointByLen(startPnt, dirPnt, length) {
  dirPnt.setLength(length);
  return startPnt.clone().add(dirPnt);
}

export function computeAngle(startPnt, endPnt) {
  let lineDir = endPnt.clone().sub(startPnt.clone()).normalize();
  let xDir = new THREE.Vector3(1, 0, 0);
  let angle = lineDir.angleTo(xDir);
  angle = angle * 180 / Math.PI;
  if (lineDir.y < 0) {
    return 360 - angle;
  } else {
    return angle;
  }
}

export function createArcGetSpacedPoints(x, y, radius, startAngle, endAngle, zOffset = 0, clockwise = false) {
  let divisions = 10;
  let points = [];
  let arc = new THREE.ArcCurve(x, y, radius, startAngle * Math.PI / 180, endAngle * Math.PI / 180, clockwise);
  let spacedPoints = arc.getSpacedPoints(divisions);
  for (let i = 0; i < spacedPoints.length; i++) {
    let item = spacedPoints[i];
    let pnt = new THREE.Vector3(item.x, item.y, zOffset);
    if (i > 0 && i < spacedPoints.length - 1) {
      pnt.isFilletPnt = true;
    }
    points.push(pnt);
  }
  return points;
}

// 计算两圆交点
export function computeIntersectPnts2Circles(center0, radius0, center1, radius1) {
  let res = {
    pointNum: 0,
    p1: null,
    p2: null
  };
  if (center0.equals(center1) && radius0 === radius1)
    return res;
  let x0 = center0.x;
  let y0 = center0.y;
  let x1 = center1.x;
  let y1 = center1.y;

  //判断两圆位置关系， 相离、相切、相交
  let l = center0.distanceTo(center1);
  if (l === radius0 + radius1) {//外切
    res.pointNum = 1;
    let v0 = new THREE.Vector3(x1 - x0, y1 - y0, 0);
    let k = radius0 / (radius0 + radius1);
    res.p1 = new THREE.Vector3(x0 + k * v0.x, y0 + k * v0.y, 0);
  } else if (l === Math.abs(radius0 - radius1)) {
    res.pointNum = 1;
    if (radius0 > radius1) {
      let v0 = new THREE.Vector3(x1 - x0, y1 - y0, 0);
      let k = radius0 / l;
      res.p1 = new THREE.Vector3(x0 + k * v0.x, y0 + k * v0.y, 0);
    } else if (radius0 < radius1) {
      let v0 = new THREE.Vector3(x0 - x1, y0 - y1, 0);
      let k = radius1 / l;
      res.p1 = new THREE.Vector3(x1 + k * v0.x, y1 + k * v0.y, 0);
    }
  } else if (l < (radius0 + radius1) && l > Math.abs(radius0 - radius1)) {//相交时
    res.pointNum = 2;
    let A0 = x1 - x0;
    let B0 = y1 - y0;
    let C0 = radius0 * radius0 - radius1 * radius1;
    let C1 = (C0 + A0 * (x0 + x1) + B0 * (y0 + y1)) / 2;
    if (Math.abs(B0) < Math.abs(Err)) {//为0
      let D = radius0 * radius0 - (C1 / A0 - x0) * (C1 / A0 - x0);
      let cl0x = C1 / A0;
      let cl0y = Math.sqrt(D) + y0;
      let cl1x = C1 / A0;
      let cl1y = y0 - Math.sqrt(D);
      res.p1 = new THREE.Vector3(cl0x, cl0y, 0);
      res.p2 = new THREE.Vector3(cl1x, cl1y, 0);
    } else {
      let E = C1 - B0 * y0;
      let F = A0 * A0 + B0 * B0;
      let G = -2 * B0 * B0 * x0 - 2 * A0 * E;
      let H = B0 * B0 * x0 * x0 + E * E - B0 * B0 * radius0 * radius0;
      let cl0x = (-1 * G + Math.sqrt(G * G - 4 * F * H)) / (2 * F);
      let cl0y = (C1 - A0 * cl0x) / B0;

      let cl1x = (-1 * G - Math.sqrt(G * G - 4 * F * H)) / (2 * F);
      let cl1y = (C1 - A0 * cl1x) / B0;
      res.p1 = new THREE.Vector3(cl0x, cl0y, 0);
      res.p2 = new THREE.Vector3(cl1x, cl1y, 0);
    }
  }
  return res;
}

//已知圆外一点，计算圆上切点
export function computeCircleTangent (outPnt, center, radius) {
  let res = [];
  //判断点是否在圆外
  if (outPnt.distanceTo(center) <= radius)
    return res;
  let P0 = new THREE.Vector3(outPnt.x - center.x, outPnt.y - center.y, outPnt.z - center.z);
  if (P0.y === 0) {
    let A = radius * radius / P0.x;
    let B = Math.sqrt(radius * radius - radius * radius * radius * radius / (P0.x * P0.x));
    res.push(new THREE.Vector3(A + center.x, B + center.y, center.z));
    res.push(new THREE.Vector3(A + center.x, center.y - B, center.z));
  } else {
    let a = P0.x * P0.x + P0.y * P0.y;
    let b = -2 * radius * radius * P0.x;
    let c = -1 * radius * radius * P0.y * P0.y + radius * radius * radius * radius;
    let A = Math.sqrt(b * b - 4 * a * c);
    let x0 = (-1 * b + A) / (2 * a);
    let y0 = (radius * radius - x0 * P0.x) / P0.y;
    let x1 = (-1 * b - A) / (2 * a);
    let y1 = (radius * radius - x1 * P0.x) / P0.y;
    res.push(new THREE.Vector3(x0 + center.x, y0 + center.y, center.z));
    res.push(new THREE.Vector3(x1 + center.x, y1 + center.y, center.z));
  }
  return res;
}


